import { groupBy, range, type IAny } from '@/utils'
import { BorderType, type FUniver, type TextStyleValue } from '@univerjs/presets'
import type { FRange } from '@univerjs/presets/lib/types/preset-sheets-core/index.js'
import { ref } from 'vue'

/**
 * 数据预处理（保持原有逻辑）
 * @param data
 * @returns
 */
const useFormDataMap = (data: IFormDataIntervalDto[]) => {
  const reqDataJson = data.map<{
    createUserName: string
    createTime: string
    formName: string
    [key: string]: string | number | boolean | Date
  }>((item) => ({
    createUserName: item.createUserName,
    createTime: item.createTime,
    formName: item.formName,
    ...JSON.parse(item.formData),
  }))

  //#region 数据字段获取

  // 遍历reqDataJson第一个数据, 并将字段保存到变量中
  const reqDataKeys = ref<string[]>([])
  for (const valueKey in reqDataJson[0]) reqDataKeys.value.push(`$arr{${valueKey}}`)

  // // 遍历reqDataJson第一个数据, 并将字段保存到变量中
  // const getReqDataKeys = (key: string = '$arr') => {
  //   // 默认是 $arr
  //   const reqDataKeys = ref<string[]>([])
  //   for (const valueKey in reqDataJson[0]) reqDataKeys.value.push(`${key}{${valueKey}}`)
  //   return reqDataKeys
  // }
  //#endregion

  return { reqDataJson, reqDataKeys }
}

/**
 * 增加一些, 基本字段, 如: 当前时间, 当前表单名称, 当前表单创建人等, 展示表单基本信息内容
 * @returns
 */
const useGetFormData = () => {
  const formData = ref<{
    [name: string]: string
  }>({
    name: '静脉用药调配中心（太白湖）',
    tableName: '调配间清场登记表',
    input_1596781096796: '测试内容',
    textarea_1596781097946: '你好啊',
    select_1596781098828: '1',
    radio_1596781099911: '1',
    date_1596781101081: 'yyyy-07-Fr',
    select_1596781098828_label: '下拉框1',
    radio_1596781099911_label: '选项1',
  })
  formData.value['currentTime'] = new Date().toLocaleString()

  // 表单字段
  const formKeys: string[] = []
  for (const valueKey in formData.value) formKeys.push(`{${valueKey}}`)

  return { formData, formKeys }
}

export class SheetRenderer {
  public async renderHx(fUniver: FUniver, data: IFormDataIntervalDto[]) {
    // sheetData 获取到的数据 大致为以下内容:
    // {"0":{"0":{"s":"aNtoQc","v":"日期","t":1},"1":{"s":"aNtoQc"},"2":{"s":"XCeFdC","v":"$group{date}","t":1}},"1":{"0":{"s":"U-5eY1","v":"上午 7:00 - 9:00","t":1},"1":{"s":"ooidgK","v":"冷藏室温度","t":1},"2":{"s":"yLuZ8d","v":"$groupItem1{tem}","t":1}},"2":{"0":{"s":"s0HnCU","v":"温度监测记录（签字）","t":1},"1":{"s":"s0HnCU"},"2":{"s":"yLuZ8d","v":"$groupItem1{createUserName}","t":1}},"3":{"0":{"s":"s0HnCU","v":"温度监测记录（时间）","t":1},"1":{"s":"s0HnCU"},"2":{"s":"yLuZ8d","v":"$groupItem1{createTime}","t":1}},"4":{"0":{"s":"aw6b-k","v":"下午 15:00 - 17:00","t":1},"1":{"s":"ooidgK","v":"冷藏室温度","t":1},"2":{"s":"yLuZ8d","v":"$groupItem2{tem}","t":1}},"5":{"0":{"s":"s0HnCU","v":"温度监测记录（签字）","t":1},"1":{"s":"s0HnCU"},"2":{"s":"yLuZ8d","v":"$groupItem2{createUserName}","t":1}},"6":{"0":{"s":"s0HnCU","v":"温度监测记录（时间）","t":1},"1":{"s":"s0HnCU"},"2":{"s":"yLuZ8d","v":"$groupItem2{createTime}","t":1}},"7":{"0":{"s":"5ABV69","v":"清洁除霜记录（签字）","t":1},"1":{"s":"5ABV69"},"2":{"s":"dVNVHb","v":"$groupent{isDefrost}","t":1}},"8":{"0":{"s":"5ABV69"},"1":{"s":"5ABV69"},"2":{"s":"dVNVHb"}}}
    // 获取当前工作表实例
    const activeWorkbook = fUniver.getActiveWorkbook()
    const activeSheet = activeWorkbook?.getActiveSheet()

    //#region 数据处理

    // 数据预处理（保持原有逻辑）
    const { reqDataJson } = useFormDataMap(data)
    const reqDataKeys: string[] = ['$group{date}']

    // 增加一些, 基本字段, 如: 当前时间, 当前表单名称, 当前表单创建人等, 展示表单基本信息内容
    const { formData, formKeys } = useGetFormData()

    //#endregion

    //#region 单元格赋值
    const sheetData = activeSheet?.getSheet().getSnapshot().cellData

    // 判断是否已经拓展过行/列 (插入行列)
    let isExpand = false

    // 如果在单元格中找到了组($group{xxx}), 则需要尝试生成 组的子项
    const groupItemKeys: string[] = []
    let group: {
      [
        key: string | number
      ]: // | IAny | { [key: string | number]: IAny } | Array<IAny | { [key: string | number]: IAny }>
      Array<IAny | { [key: string | number]: IAny }>
    } = {}

    // 0, 1
    for (const rowItem in sheetData) {
      const rowIndex = Number.parseInt(rowItem)

      // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
      for (const colItem in sheetData[rowIndex]) {
        const colIndex = Number.parseInt(colItem)

        const cell = sheetData[rowIndex][colIndex]
        const cellData = cell?.v?.toString() ?? ''
        if (!cellData) continue

        // 基础字段判断
        // 判断 table 内容是否包含 从 formData 中迭代的字段, 如果包含则将table内容进行替换
        if (formKeys.indexOf(cellData) > -1) {
          const key = cellData.replace('{', '').replace('}', '')
          // 将表格中的内容进行替换
          activeSheet?.getRange(rowIndex, colIndex)!.setValue(formData.value[key].toString())
        }

        // 从当前字段中获取到 $arr{...}
        const curCellDataMatch = cellData?.match(/\$group\{(\w+)\}/)?.[0] ?? ''
        // 生成分组的字段, 并附带单元格样式
        if (reqDataKeys.indexOf(curCellDataMatch) > -1) {
          // 将内容进行拆分, 获取到当前字段内容 $arr{...} {} 里的字段, 并将内容进行循环赋值
          const reqFormDataKey = curCellDataMatch.replace('$group{', '').replace('}', '')

          group = groupBy(reqDataJson, reqFormDataKey)
          if (!group) throw new Error('请配置正确的分组项目')

          const length = Array.isArray(group[Object.keys(group)[0]])
            ? group[Object.keys(group)[0]].length
            : 1

          range(1, length).forEach((item) => {
            for (const key in length === 1
              ? group[Object.keys(group)[0]]
              : group[Object.keys(group)[0]][0]) {
              groupItemKeys.push(`$groupItem${item - 1}{${key}}`)
              groupItemKeys.push(`$groupItem{${key}}`)
            }
          })
          // console.log(groupItemKeys)

          let cellStyle: FRange | null
          for (let i = 0; i < Object.keys(group).length; i++) {
            const groupIndex = Object.keys(group)[i]
            const range = activeSheet?.getRange(rowIndex, colIndex + i)!

            if (i === 0) cellStyle = range
            // 插入行操作
            if (!isExpand) {
              // 清空该单元格
              range.clearContent()
              activeSheet?.insertColumnAfter(colIndex + i + 1)
            }
            const style = cellStyle!.getCellStyleData()

            range.setValue({
              v: groupIndex.toString(),
              s: { ...style, tb: 1 }, // 文本溢出, 让后续的自动修改列宽进行调整
            })
          }
          // 插入行操作
          if (!isExpand) isExpand = true
        } else if (groupItemKeys.length > 0 && groupItemKeys.indexOf(cellData) > -1) {
          // 生成分组下的数组字段, 并附带单元格样式
          const regexSingleField = /\$(\w+)(\d+)\{(.*?)\}/ // 匹配单个数组的单个字段
          const regexMultipleFields = /\$(\w+)\{(.*?)\}/ // 匹配多个数组的单个字段

          // console.log(
          //   'regexSingleField',
          //   regexSingleField.test(cellData),
          //   regexMultipleFields.test(cellData),
          //   cellData,
          // )
          // console.log(regexSingleField.test(cellData) && regexMultipleFields.test(cellData))

          if (regexSingleField.test(cellData)) {
            // 赋值分组项属性
            const { field, funcName, index } = this.regexExtract(regexSingleField, cellData)

            if (!field) continue

            if (funcName == 'groupItem') {
              let cellStyle: FRange | null
              for (let i = 0; i < Object.keys(group).length; i++) {
                const value = group[Object.keys(group)[i]][index][field]

                const range = activeSheet?.getRange(rowIndex, colIndex + i)!
                if (i === 0) cellStyle = range
                // 插入行操作
                if (!isExpand) {
                  // 清空该单元格
                  range.clearContent()
                  activeSheet?.insertColumnAfter(colIndex + i + 1)
                }
                const style = cellStyle!.getCellStyleData()
                // console.log(style)

                range.setValue({
                  v: value.toString(),
                  s: { ...style, tb: 1 }, // 文本溢出, 让后续的自动修改列宽进行调整
                })
              }
            }
          } else if (regexMultipleFields.test(cellData)) {
            // 赋值分组项属性
            const regex = regexMultipleFields // 正则表达式
            const matchValue = regex.exec(cellData)

            const funcName = matchValue?.[1] ?? ''
            const field = matchValue?.[2] ?? ''

            if (!field) continue

            if (funcName == 'groupItem') {
              let cellStyle: FRange | null
              for (let i = 0; i < Object.keys(group).length; i++) {
                const value = group[Object.keys(group)[i]].map((m) => m[field]).join('/')

                const range = activeSheet?.getRange(rowIndex, colIndex + i)!
                if (i === 0) cellStyle = range
                // 插入行操作
                if (!isExpand) {
                  // 清空该单元格
                  range.clearContent()
                  activeSheet?.insertColumnAfter(colIndex + i + 1)
                }
                const style = cellStyle!.getCellStyleData()
                range.setValue({
                  v: value.toString(),
                  s: { ...style, tb: 1 }, // 文本溢出, 让后续的自动修改列宽进行调整
                })
              }
            }
          }
        }
      }
    }

    // 自动调整所有列宽(后续: 检查为什么异常)
    const maxColumnCount =
      fUniver.getActiveWorkbook()?.getActiveSheet()?.getSheet()?.getColumnCount() ?? 0 // 获取总列数

    setTimeout(() => {
      activeSheet?.autoResizeColumns(0, maxColumnCount)
    }, 1000)

    //#endregion
  }

  private regexExtract(regexSingleField: RegExp, cellData: string) {
    const regex = regexSingleField // 正则表达式
    // 第一次没有获取到 ???
    const matchVal = regex.exec(cellData)
    const aaa = regex.exec(cellData)

    const funcName = aaa?.[1] ?? ''
    const index = Number.parseInt(aaa?.[2] ?? '')
    const field = aaa?.[3] ?? ''
    return { field, funcName, index }
  }

  public async renderZx(fUniver: FUniver, data: IFormDataIntervalDto[]) {
    // sheetData 获取到的数据 大致为以下内容:
    //  {"0":{"0":{"s":"MCuXpP","v":"所属科室","t":1},"1":{"s":"MCuXpP","v":"输液标签条码","t":1},"2":{"s":"MCuXpP","v":"主要涉及药品","t":1},"3":{"s":"MCuXpP","v":"标签是否完整","t":1},"4":{"s":"MCuXpP","v":"各工序是否完成","t":1},"5":{"s":"MCuXpP","v":"外观是否完整","t":1},"6":{"s":"MCuXpP","v":"是否渗透","t":1},"7":{"s":"MCuXpP","v":"是否有异物","t":1},"8":{"s":"MCuXpP","v":"所抽科室理论数与实物是否一致","t":1},"9":{"s":"MCuXpP","v":"备注","t":1},"10":{"s":"MCuXpP","v":"提交人","t":1},"11":{"s":"MCuXpP","v":"提交时间","t":1}},"1":{"0":{"s":"MCuXpP","v":"$arr{dept}","t":1},"1":{"s":"MCuXpP","v":"$arr{barCode}","t":1},"2":{"s":"MCuXpP","v":"$arr{drug}","t":1},"3":{"s":"MCuXpP","v":"$arr{isTagFull}","t":1},"4":{"s":"MCuXpP","v":"$arr{isDone}","t":1},"5":{"s":"MCuXpP","v":"$arr{isFull}","t":1},"6":{"s":"MCuXpP","v":"$arr{isInfiltration}","t":1},"7":{"s":"MCuXpP","v":"$arr{hasforeignBody}","t":1},"8":{"s":"MCuXpP","v":"$arr{IsConsistent}","t":1},"9":{"s":"MCuXpP","v":"$arr{remark}","t":1},"10":{"s":"MCuXpP","v":"$arr{createUserName}","t":1},"11":{"s":"MCuXpP","v":"$arr{createTime}","t":1}}}

    // 获取当前工作表实例
    const activeWorkbook = fUniver.getActiveWorkbook()
    const activeSheet = activeWorkbook?.getActiveSheet()

    //#region 数据处理

    // 数据预处理（保持原有逻辑）
    const { reqDataJson, reqDataKeys } = useFormDataMap(data)

    // 增加一些, 基本字段, 如: 当前时间, 当前表单名称, 当前表单创建人等, 展示表单基本信息内容
    const { formData, formKeys } = useGetFormData()

    //#endregion

    //#region 单元格赋值

    const sheetData = activeSheet?.getSheet().getSnapshot().cellData

    // 判断是否已经拓展过行/列 (插入行列)
    let isExpand = false

    // 0, 1
    for (const rowItem in sheetData) {
      const rowIndex = Number.parseInt(rowItem)

      // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
      for (const colItem in sheetData[rowIndex]) {
        const colIndex = Number.parseInt(colItem)

        const { s, v, t } = sheetData[rowIndex][colIndex]
        const cellData = v?.toString() ?? ''

        // 基础字段判断
        // 判断 table 内容是否包含 从 formData 中迭代的字段, 如果包含则将table内容进行替换
        if (formKeys.indexOf(cellData) > -1) {
          const key = cellData.replace('{', '').replace('}', '')
          // 将表格中的内容进行替换
          activeSheet?.getRange(rowIndex, colIndex)!.setValue(formData.value[key].toString())
        }

        // 从当前字段中获取到 $arr{...}
        const curCellDataMatch = cellData?.match(/\$arr\{(\w+)\}/)?.[0] ?? ''
        // 纵向设置判断
        // 判断 table 内容是否包含 reqData 中迭代的字段, 如果包含则将table内容进行替换
        // 如果有数据, 则增加一行, 并且判断一下值是否大于/小于给定条件, 更改颜色/显示其他内容
        if (reqDataKeys.value.indexOf(curCellDataMatch) > -1) {
          // 将内容进行拆分, 获取到当前字段内容 $arr{...} {} 里的字段, 并将内容进行循环赋值
          const reqFormDataKey = curCellDataMatch.replace('$arr{', '').replace('}', '')

          // 由于 该字段是数组, 需要将内容循环进行添加(按照当前内容的行数向下进行添加)
          for (let j = 0; j < reqDataJson.length; j++) {
            const cell = activeSheet?.getRange(rowIndex + j, colIndex)!
            // 插入行操作
            if (!isExpand) {
              // 清空该单元格
              cell.clear()
              activeSheet?.insertRowsAfter(rowIndex + j + 1, 1)
            }
            // 判断如果存在颜色规则, 则为当前单元格设置颜色
            if (cellData.match(/\.color\(([^)]+)\)/)?.[0]) {
              const color = cellData.replace(
                /\$arr\{(\w+)\}\.color\(([^)]+)\)/,
                function (match, key, colorCondition) {
                  // 在上下文获取到 value, 通过eval进行调用
                  // 当前 值
                  const value = reqDataJson[j][reqFormDataKey]
                  // 当前 行值
                  const row = reqDataJson[j]

                  // 动态计算颜色
                  // value=="合格"? blue:red
                  const getColor = new Function('value', 'row', `return ${colorCondition}`)
                  // 防止 打包后参数简化, eval 无法执行动态脚本
                  return getColor(value, row)
                },
              )
              cell.setFontColor(color)
            }

            cell.setValue(reqDataJson[j][reqFormDataKey].toString())
          }
          // 插入行操作
          if (!isExpand) isExpand = true
        }
      }
    }

    // 自动调整所有列宽(后续: 检查为什么异常)
    const maxColumnCount =
      fUniver.getActiveWorkbook()?.getActiveSheet()?.getSheet()?.getColumnCount() ?? 0 // 获取总列数

    setTimeout(() => {
      activeSheet?.autoResizeColumns(0, maxColumnCount)
    }, 1000)

    // // 批量执行命令（性能优化关键）
    // await this._commandService.executeCommands(commands)

    // // 设置初始选区（如果需要）
    // await this._commandService.executeCommand(SetSelectionsCommand.id, {
    //   workbookId: activeWorkbook.getUnitId(),
    //   worksheetId: sheetId,
    //   selections: [
    //     {
    //       range: {
    //         startRow: 0,
    //         endRow: 0,
    //         startColumn: 0,
    //         endColumn: 0,
    //       },
    //     },
    //   ],
    // })

    //#endregion
  }

  // 门面: 判断该调用那个渲染函数
  public async render(fUniver: FUniver, data: IFormDataIntervalDto[]) {
    // 获取sheetData 数据 -> 是获取workbookData中的sheet中的cellData
    const activeWorkbook = fUniver?.getActiveWorkbook()
    if (!activeWorkbook) throw new Error('activeWorkbook is not defined')

    const snapshot = activeWorkbook.getSnapshot()
    const sheet1 = Object.values(snapshot.sheets)[0].cellData
    for (const row in sheet1!) {
      for (const col in sheet1[row]!) {
        if (/\$group\{(\w+)\}/.test(sheet1[row][col]?.v?.toString() ?? '')) {
          this.renderHx(fUniver, data)
          return
        } else if (/\$arr\{(\w+)\}/.test(sheet1[row][col]?.v?.toString() ?? '')) {
          this.renderZx(fUniver, data)
        }
      }
    }
  }
}

export interface IFormDataIntervalDto {
  storage: string
  id: string
  temId: string
  formId: string
  formName: string
  formData: string
  remark: string
  enabled: boolean
  createUser: string
  createUserName: string
  createTime: string
  lastUpdateUser: string
  lastUpdateTime: string
  state: number
  stateName: string
  scheduleId: string | null
  isTimeOut: boolean
  isValidFail: boolean
}
